package juc.work;

import java.util.ArrayList;
import java.util.List;

public class ConsumerAndProducer {
    // 手写生产者消费者
    private static int MAX_CAPACITY = 100;
    private List<Object> list = new ArrayList<>();

    // 生产
    public void produce(int num) {
        synchronized (list) {
            while(list.size() + num > MAX_CAPACITY) {
                System.out.println("Buffer is full and wait to consume");
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            for(int i = 0; i < num; i++) {
                list.add(new Object());
            }
            System.out.println("Produce " + num + " items");
            list.notifyAll();
        }
    }

    //消费
    public void consume(int num) {
        synchronized(list) {
            while(list.size() < num) {
                System.out.println("Buffer is empty and wait to produce");
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            for(int i = 0; i < num; i++) {
                list.remove(0);
            }
            System.out.println("Consume " + num + " items");
            list.notifyAll();
        }
    }

    class Producer implements Runnable {
        private ConsumerAndProducer cp;
        private int num;
        public Producer(ConsumerAndProducer cp, int num) {
            this.cp = cp;
            this.num = num;
        }
        @Override
        public void run() {
            cp.produce(this.num);
        }
    }

    class Consumer implements Runnable {
        private ConsumerAndProducer cp;
        private int num;
        public Consumer(ConsumerAndProducer cp, int num) {
            this.cp = cp;
            this.num = num;
        }
        @Override
        public void run() {
            cp.consume(this.num);
        }
    }

    public static void main(String[] args) {
        ConsumerAndProducer cp = new ConsumerAndProducer();
        for(int i = 0; i < 10; i++) {
            new Thread(cp.new Producer(cp, 10)).start();
            new Thread(cp.new Consumer(cp, 10)).start();
        }
    }
}
